/*
    OxpontIRremotePwm.cpp 红外遥控器接收
    木牛流马-华休
    2020年11月17号
*/

#include "OxpontIRremotePwm.h"
#include <Arduino.h>

bool IRremote_flag=false;//能否接收红外
uint8_t recvpin;//红外接收引脚
uint8_t key_count=0;//固定周期检测红外值
uint8_t key_start=0;//开启取值
uint8_t key_clear=0;//清空key_value
uint8_t key_value_temp[2]={0};//
uint8_t key_value[2];
uint8_t count=0;

//PWM生成部分
bool pwm_pin[20]={false};//引脚是否开启PWM
volatile uint8_t pwm_count[20]={0};//占空比 pwm_count/256
volatile uint8_t pwm_level[20]={3};//记录引脚的高低电平，3是初始状态，0是低，1是高



//初始化 初始化定时器。
// OxpontIRremotePwm::OxpontIRremotePwm()
// {
  // cli();////关闭全局中断
  // //设置定时器2为8kHz
  // TCCR2A = 0;// set entire TCCR2A register to 0
  // TCCR2B = 0;// same for TCCR2B
  // TCNT2  = 0;//initialize counter value to 0
  // // set compare match register for 8khz increments
  // OCR2A = 228;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // // turn on CTC mode
  // TCCR2A |= (1 << WGM21);//打开CTC模式
  // // Set CS21 bit for 8 prescaler
  // TCCR2B |= (1 << CS21);   
  // // enable timer compare interrupt
  // TIMSK2 |= (1 << OCIE2A);   
  // sei();//打开全局中断
 
// }
//开始定时器
void OxpontIRremotePwm::enableTimer2()
{
  cli();////关闭全局中断
  //设置定时器2为8kHz
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  // set compare match register for 8khz increments
  OCR2A = 114;// = (16*10^6) / (8000*8) - 1 (must be <256) 114
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);//打开CTC模式
  // Set CS21 bit for 8 prescaler
  TCCR2B |= (1 << CS21);   
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);   
  sei();//打开全局中断

}

void OxpontIRremotePwm::disableTimer2()
{
   TIMSK2 = 0;
}

//使能接收，传入接收引脚
void OxpontIRremotePwm::enableIRIn(uint8_t pin)
{  
  

    recvpin=pin;
    pinMode(recvpin,INPUT);//设置为输入模式
    IRremote_flag=true;
    
 
}

void OxpontIRremotePwm::disableIRIn()//终止接收。
{
    // TIMSK2 = 0;
    IRremote_flag=false;
}

//开启PWM
void OxpontIRremotePwm::pwmWrite(uint8_t pin,uint8_t count)
{  
  if(pin>=0&&pin<=19)
  {
    pinMode(pin,OUTPUT);//设置为输出模式
    pwm_count[pin]=count;
    pwm_pin[pin]=true;
  }  
}


//关闭PWM 
void OxpontIRremotePwm::disablePwm(uint8_t pin)
{
    if(pin>=0&&pin<=19)
  {
    pwm_count[pin]=0;
    pwm_pin[pin]=false;
    // digitalWrite(pin,0);
  } 
}
//关闭PWM 指定关闭时引脚的状态
void OxpontIRremotePwm::disablePwm(uint8_t pin,uint8_t level)
{
    if(pin>=0&&pin<=19)
  {
    pwm_count[pin]=0;
    pwm_pin[pin]=false;
    digitalWrite(pin,level);
  } 
}

//获取键值
uint8_t OxpontIRremotePwm::getKey()
{
  return key_value[0];
}
//获取频道
uint8_t OxpontIRremotePwm::getChannel()
{
  if(key_value[1]>0)
  {
    uint8_t chan_value[8]={0x6A,0x5A,0x56,0x55,0x54,0x52,0x4A,0x2A};
    for(int i=0;i<8;i++)
    {
      if(chan_value[i]==key_value[1])
      {
        return i+1;
      }
    }
  }
  return 0;
}


ISR(TIMER2_COMPA_vect)
{// timer1中断8kHz切换引脚9
  //产生频率为8kHz / 2 = 4kHz的脉冲波（全波切换为两个周期，然后切换为低）
  if(IRremote_flag)//是否启用IRremote_flag
  {
      if((digitalRead(recvpin)==0)&&(key_start==0))
    {
      key_start=19;
      key_count=8;
      key_value_temp[0]=0;
      key_value_temp[1]=0;
    }
    if((count%24)==0)
    {
      if(key_clear>0)
      {
        key_clear--;
      }
    }
    if(key_clear==0)
    {
      key_value[0]=0;
      key_value[1]=0;
    }
    if(key_count>=6)
    {
        key_start--;
        key_count=0;
        
        if((key_start>0)&&(key_start<17))
        {

          
          if(key_start>8)
          {         
            if(digitalRead(recvpin)==1)
            {          
              key_value_temp[0]=key_value_temp[0]|(0x01<<(key_start-9));
            }         
          }
          else
          {
            if(digitalRead(recvpin)==1)
            {
              key_value_temp[1]=key_value_temp[1]|(0x01<<(key_start-1));
            }
          }
          if(key_start==1)
          {

            key_value[0]=key_value_temp[0];
            key_value[1]=key_value_temp[1];
            key_clear=0x88;



            // uint8_t chan_value[8]={0x6A,0x5A,0x56,0x55,0x54,0x52,0x4A,0x2A};
            // if(chan_value[channel-1]==key_value_temp[1])
            // {
            //   key_value[0]=key_value_temp[0];
            //   key_value[1]=key_value_temp[1];
            //   key_clear=0x88;
            // }
            //检测是否是F4按下，
            // else if(key_value_temp[0]==0x26)
            // {
            //   for(int i=0;i<8;i++)
            //   {
            //     if(chan_value[i]==key_value_temp[1])
            //     {
            //       channel=i+1;
            //     }
            //   }
            // }
          }
        }
        else if(digitalRead(recvpin)==1)
        {
          //前两个数据应该一直是低电平，如果不是则说明数据异常，不需要再接收了
          key_start=0;//数据异常
        }
  
    }
    if(key_start>0)
      {
        key_count++;
      } 
  }
  // 产生PWM波
  for(uint8_t i=0;i<20;i++)
  {
    if(pwm_pin[i])//如果开启了PWM
    {
      if(pwm_count[i]>=count)
      {
        if(pwm_level[i]!=1)
        {
          //输出高
          digitalWrite(i,1);
          pwm_level[i]=1;

        }
       
      }
      else
      {
        if(pwm_level[i]!=0)
        {
          /* 输出低 */
          digitalWrite(i,0);
          pwm_level[i]=0;

        }
      }
      
    }
  }
  count++;
  if(count>=0xff)
  {
    count=0;
  }

}

